
#ifndef __COMMH_MSG_H__
#define __COMMH_MSG_H__

#include "CTMsgBase.h"
#include "CTCodeUpdate.h"
#include "CTKeyValue.h"
#include "commclass.h"

enum
{
    EMAX_SQLLEN = 40960,     ///< SQL语句的最大长度
    EMAX_RESULTMSG = 1024,      ///< 最大错误描述
};

/** 消息ID定义 */
enum enumMsgID
{
    // 1000~1999 是client发向mainsvr的消息, 程序内会根据这个段来检查安全性
    //注意新增跟前台通信的命令ID时, 需要使用奇数
    ID_MAIN_MIN                         = 1000,
    ID_MAIN_MAX                         = 1999,
    ID_MAIN_LOGIN                       = ID_MAIN_MIN + 1,
    ID_MAIN_LOGOUT                      = ID_MAIN_MIN + 3,
    ID_MAIN_MATCH_RIVAL                 = ID_MAIN_MIN + 5,
    ID_MAIN_ENTER_ROOM                  = ID_MAIN_MIN + 7,
    ID_MAIN_LEAVE_ROOM                  = ID_MAIN_MIN + 9,
    ID_MAIN_BATTLE                      = ID_MAIN_MIN + 11,
    ID_MAIN_GET_TASK                    = ID_MAIN_MIN + 13,
    ID_MAIN_CARD	                    = ID_MAIN_MIN + 15,
    ID_MAIN_DECK	                    = ID_MAIN_MIN + 17,
    ID_MAIN_NOTIFY                      = ID_MAIN_MIN + 19,
    ID_MAIN_FRIEND                      = ID_MAIN_MIN + 21,
    ID_MAIN_TIPS		                = ID_MAIN_MIN + 23,
    ID_MAIN_SHOP			            = ID_MAIN_MIN + 25,
    ID_MAIN_QUALIFYING			        = ID_MAIN_MIN + 27,
    ID_MAIN_LOGIN_REWARD                = ID_MAIN_MIN + 29, //登录奖励
    ID_MAIN_ARENA			            = ID_MAIN_MIN + 31, //竞技场协议
    ID_MAIN_USER_GUIDE                  = ID_MAIN_MIN + 33, //用户引导
    ID_MAIN_VIP								= ID_MAIN_MIN + 35, //用户VIP
    ID_MAIN_GROWTHFUND				= ID_MAIN_MIN + 37, //成长基金
    ID_MAIN_FIRSTRECHARGE				= ID_MAIN_MIN + 39, //首冲
    ID_MAIN_CARDUPGRADE				= ID_MAIN_MIN + 41,//卡牌升级
    ID_MAIN_MAIL							= ID_MAIN_MIN + 43,//邮件

    //注意新增跟前台通信的命令ID时, 需要使用奇数

    // 2000~2099 是mainsvr发向dbsvr的消息
    ID_MAINDB_MIN                       = 2000,
    ID_MAINDB_MAX                       = 2099,
    ID_MAINDB_UPDATEDATA                = ID_MAINDB_MIN + 0,
    ID_MAINDB_SELECTDATA                = ID_MAINDB_MIN + 1,
    ID_MAINDB_MAINCTRL_INITDATA         = ID_MAINDB_MIN + 2,

    // 2100~2199 是mainsvr发向apisvr的消息
    ID_MAINAPI_MIN                      = 2100,
    ID_MAINAPI_MAX                      = 2199,
    ID_MAINAPI_TAPI                     = ID_MAINAPI_MIN + 1, //腾讯open api接口

    // 3000~3999 dbsvr->mpsvr
    ID_DBSVR_MIN                        = 3000,
    ID_DBSVR_MAX                        = 3999,
    ID_DB_SQL                           = ID_DBSVR_MIN + 0,
    ID_DB_ANS                           = ID_DBSVR_MIN + 1,
    ID_DB_INNER_INITDATA                = ID_DBSVR_MIN + 2,
    ID_DB_INNER_UPDATEDATA              = ID_DBSVR_MIN + 3,

    // 4000~4999 mainsvr inner
    ID_MAIN_INNER_MIN                   = 4000,
    ID_MAIN_INNER_MAX                   = 4999,
    ID_MAIN_INNER_CHECK_EXIST           = ID_MAIN_INNER_MIN + 0,
    ID_MAIN_INNER_CHECK_NAME            = ID_MAIN_INNER_MIN + 1,
    ID_MAIN_INNER_CREATE_USER           = ID_MAIN_INNER_MIN + 2,
    ID_MAIN_INNER_DROP_ITEM             = ID_MAIN_INNER_MIN + 3,

		ID_MAIN_INNER_ACT_TITLE             = ID_MAIN_INNER_MIN + 4,  //主动下发活动以及称号


    // 5000~5999 内部protobuf发送gm指令
    ID_MAIN_GM_MIN                      = 5000,
    ID_MAIN_GM_MAX                      = 5999,
    ID_MAIN_GM_PLAYER                   = ID_MAIN_GM_MIN + 0,

    //6000~6999 apisvr -> mpsvr
    ID_INTER_API_MIN                    = 6000,
    ID_INTER_API_MAX                    = 6999,
    ID_INTER_API_TENCENT                = ID_INTER_API_MIN + 1, //腾讯平台接口

    //防沉迷需要的命令编号
    ID_MAIN_DEFEND                      = 10000,
    ID_MAIN_GET_DEFEND_INFO             = ID_MAIN_DEFEND + 1, //防沉迷
    ID_MAIN_COMMIT_DEFEND_INFO          = ID_MAIN_DEFEND + 3,
    ID_MAIN_COMMIT_DEFEND_OTHER         = ID_MAIN_DEFEND + 5,

    ID_MAIN_CMD_MAX                     = 11000,
};

enum ENUM_GM_PLAYER_SUB_CMD
{
    ID_GM_PLAYER_SUB_GET_HELP               = 0,            //获取帮助信息
    ID_GM_PLAYER_SUB_INFO_TOKEN             = 1,            //通过token获取角色基本信息
    ID_GM_PLAYER_SUB_INFO_NAME              = 2,            //通过昵称获取角色基本信息
    ID_GM_PLAYER_SUB_INFO_GID               = 3,            //通过GID获取角色基本信息
    ID_GM_PLAYER_SUB_BATTLE_INFO            = 4,            //通过token获取角色战斗信息
    ID_GM_DAILY_TASK_CONFIG					= 5,			//获得日常任务的配置
    ID_GM_USER_DAILY_TASK					= 6, 			//获得用户的日常任务
    ID_GM_PLAYER_SUB_SET_TIME               = 7,            //修改游戏进程时间偏移
    ID_GM_USER_MODIFY_DAILY_TASK_STATUS     = 8,            //修改日常任务的状态
    ID_GM_USER_MODIFY_FRIEND				= 9, 			//修改用户的好友系统
    ID_GM_PLAYER_SUB_BATTLE_DEAL            = 10,           //通过GID操作战斗数据
    ID_GM_PLAYER_SUB_SEN_WORD_TEST          = 11,           //测试敏感词汇
    ID_GM_PLAYER_SUB_RELOAD_CONFIG          = 12,           //重新加载日志类型,Excel表格,Lua脚本
	ID_GM_PLAYER_SUB_DROP_ITEM2		        = 13,           //掉落物品(类型+参数)
    ID_GM_PLAYER_MODIFY_QUALIFYING			= 14,           //操作用户的排位赛系统	
	ID_GM_PLAYER_SUB_DROP_ITEM3				= 15,           //掉落物品((类型+子类型+参数))
	ID_GM_PLAYER_ADD_BAT_WIN_RETSULT		= 16,           //增加英雄胜利场数(英雄Id，胜利场数))
	ID_GM_PLAYER_ADD_ARENA_WIN				= 17,           //增加英雄竞技场获胜次数
	ID_GM_PLAYER_ADD_ONLINE_TIME 			= 18, 		    //修改用户在线时间
	ID_GM_PLAYER_SET_ROLE_LEVEL 			= 19, 		    //修改玩家等级(只支持向上修改)
	ID_GM_PLAYER_GET_BATTLE_VIDEO 			= 20, 		    //获取战斗录像
};

enum ENUM_GM_OFFICE_SUB_CMD
{
    ID_GM_OFFICE_SUB_GET_HELP               =  0,            //获取帮助信息
    ID_GM_OFFICE_SUB_FREEZE_LOGIN           =  1,            //以天为单位冻结玩家登录
    ID_GM_OFFICE_SUB_UNFREEZE_LOGIN         =  2,            //解冻玩家登录限制
    ID_GM_OFFICE_SUB_FREEZE_SPEAK           =  3,            //以天为单位冻结玩家发言
    ID_GM_OFFICE_SUB_UNFREEZE_SPEAK         =  4,            //解冻玩家发言限制
    ID_GM_OFFICE_SUB_FREEZE_GOLD            =  5,            //以天为单位冻结使用金币
    ID_GM_OFFICE_SUB_UNFREEZE_GOLD          =  6,            //解冻玩家使用金币限制
    ID_GM_OFFICE_SUB_FREEZE_SILVER          =  7,            //以天为单位冻结使用银币
    ID_GM_OFFICE_SUB_UNFREEZE_SILVER        =  8,            //解冻玩家使用银币限制
    ID_GM_OFFICE_SUB_FREEZE_BAG_STORGE      =  9,            //以天为单位冻结背包和仓库
    ID_GM_OFFICE_SUB_UNFREEZE_BAG_STORGE    = 10,            //解冻玩家背包和仓库限制
    ID_GM_OFFICE_SUB_SEND_ROLE_GIFT         = 11,            //发送礼包给玩家
    ID_GM_OFFICE_SUB_SEND_SYS_NOTICE        = 12,            //发送系统公告
    ID_GM_OFFICE_SUB_SYS_STOP_NOTICE        = 13,            //系统停机维护公告
    ID_GM_OFFICE_SUB_REPAIR_ROLE_HUNLI      = 14,            //修复角色魂力数据
    ID_GM_OFFICE_SUB_PULL_ALL_EQUIP         = 15,            //拉取玩家的装备数据
    ID_GM_OFFICE_SUB_GET_SYS_DATA           = 16,            //获取在线和注册
    ID_GM_OFFICE_SUB_GET_ROLE_BY_GID        = 17,            //通过GID获取角色信息
    ID_GM_OFFICE_SUB_GET_ROLE_BY_ROLENAME   = 18,            //通过昵称获取角色信息
    ID_GM_OFFICE_SUB_GET_ROLE_BY_USERTOKEN  = 19,            //通过OPENID获取角色信息
    ID_GM_OFFICE_SUB_SEND_BATCH_GIFTS       = 20,            //批量发送礼包
    ID_GM_OFFICE_SUB_SET_VIP_LEVEL          = 21,            //设置VIP等级
    ID_GM_OFFICE_SUB_STOP_OPEN_REGIST       = 22,            //设置服务器停止开放注册
    ID_GM_OFFICE_SUB_STOP_CREATE_CLAN       = 23,            //设置服务器停止创建家族
    ID_GM_OFFICE_SUB_RESET_ZONE_OPEN_TIME   = 24,            //重置开服时间并重启
};

enum ENUM_TIPS_TYPE
{
    TIPS_ACT_LIST = 10,
};

/**
* 响应的结果值.
* 该结构既是其他协议的一部分, 也是一条单独的协议
*/
class CResult: public CTCodeObject
{
public:
    int iResultID;  // 0表示正确
    CTSizeString<EMAX_RESULTMSG> szResultMsg;
};

BEGIN_CODE_CONVERT(CResult)
CODE_CONVERT(iResultID)
CODE_CONVERT(szResultMsg)
END_CODE_CONVERT(CResult)

class CReqSQL: public CTCodeObject
{
private:
    int m_iDataLen;
public:
    CTSizeString<EMAX_SQLLEN> stSQL;
    CTCodeMemory stSQLMen;

    CReqSQL()
        : m_iDataLen(0), stSQLMen(stSQL.GetBuffer(), stSQL.GetBufferLen(), m_iDataLen)
    {
    }

    int Init()
    {
        m_iDataLen = 0;
        stSQLMen.Init(stSQL.GetBuffer(), stSQL.GetBufferLen());
        return 0;
    }

    int Remove(int iLen)
    {
        if (iLen > m_iDataLen)
        {
            return -1;
        }
        else if (iLen < m_iDataLen) // 优化
        {
            memmove(stSQL.GetBuffer(), stSQL.GetBuffer() + iLen, m_iDataLen - iLen);
        }

        m_iDataLen -= iLen;
        return 0;
    }

    char *GetSqlBuffer()
    {
        return stSQLMen.GetBuffer();
    }

    int GetFreeSqlLen()
    {
        return stSQLMen.GetBufferLen() - stSQLMen.GetDataLen();
    }

    char* GetFreeSqlBuffer()
    {
        return stSQLMen.GetBuffer() + m_iDataLen;
    }

    int Append(int iLen)
    {
        m_iDataLen += iLen;
        return m_iDataLen;
    }

    int Set(const char* szFormat, ...)
    {
        m_iDataLen = 0;
        va_list ap;
        va_start(ap, szFormat);
        int iRet = VSet(szFormat, ap);
        va_end(ap);
        return iRet;
    }

    int VSet(const char * szFormat, va_list ap)
    {
        if (!szFormat)
        {
            return -1;
        }

        int iRet = ct_vsnprintf(stSQLMen.GetBuffer(), stSQLMen.GetBufferLen(), szFormat, ap);
        if (iRet < 0)
        {
            return -1;
        }

        m_iDataLen += iRet;
        return iRet;
    }

    int Cat(const char* szFormat, ...)
    {
        va_list ap;
        va_start(ap, szFormat);
        int iRet = VCat(szFormat, ap);
        va_end(ap);
        return iRet;
    }

    int VCat(const char* szFormat, va_list ap)
    {
        if (!szFormat)
        {
            return -1;
        }

        int iMaxLen = EMAX_SQLLEN - stSQLMen.GetDataLen();
        if (iMaxLen <= 0)
        {
            return -1;
        }

        int iRet = ct_vsnprintf(stSQLMen.GetBuffer() + stSQLMen.GetDataLen(), iMaxLen, szFormat, ap);
        if (iRet < 0)
        {
            return -1;
        }

        m_iDataLen += iRet;
        iRet = m_iDataLen;
        return iRet;
    }
};

BEGIN_CODE_CONVERT(CReqSQL)
CODE_CONVERT(stSQLMen)
END_CODE_CONVERT(CReqSQL)

//apisvr -> mpsvr(tencent api)
class CReqTencentApi : public CTCodeObject
{
public:
    CReqTencentApi()
        :_ucApiType(0)
    {
    }

    enum
    {
        OPEN_API  = 0,      //平台接口
        COMPASS = 1,        //罗盘
    };

    unsigned char _ucApiType;           //api类型 1: open api 2: 罗盘
    CTSizeString<50> _szApiName;        //比如:  /v3/user/get_info 
    CTLib::CTKeyValue _stKeyValue;      //请求参数
};
BEGIN_CODE_CONVERT(CReqTencentApi)
CODE_CONVERT(_ucApiType)
CODE_CONVERT(_szApiName)
CODE_CONVERT(_stKeyValue)
END_CODE_CONVERT(CReqTencentApi)

class CAnsTencentApi : public CTCodeObject
{
public:
    CResult _stResult;
    CTLib::CTKeyValue _stKeyValue;      //响应参数
};
BEGIN_CODE_CONVERT(CAnsTencentApi)
CODE_CONVERT(_stResult)
CODE_CONVERT(_stKeyValue)
END_CODE_CONVERT(CAnsTencentApi)

//mainsvr -> apisvr (ID_MAINAPI_TAPI)
class CReqApi : public CTCodeObject
{
public:
    CReqApi()
        :_ucApiType(0)
    {
    }

    enum  //请求类型
    {
        API_NULL = 0,
        API_TENCENT = 1,
    };

    unsigned char _ucReqType;               //请求类型
    unsigned char _ucApiType;               //tencent api 用, 详细的接口类型
    CTSizeString<50> _szTApiName;           //tencent api 用, 比如:  /v3/user/get_info
    CTLib::CTKeyValue _stTApiKeyValue;      //tencent api 用, 请求参数
};
BEGIN_CODE_CONVERT(CReqApi)
CODE_CONVERT(_ucReqType)
CODE_CONVERT(_ucApiType)
CODE_CONVERT(_szTApiName)
CODE_CONVERT(_stTApiKeyValue)
END_CODE_CONVERT(CReqApi)

class CAnsApi : public CTCodeObject
{
public:
    unsigned char       _ucReqType;         //请求类型
    CResult             _stResult;
    CTLib::CTKeyValue   _stTApiKeyValue;    //tencent api 用 响应参数
};
BEGIN_CODE_CONVERT(CAnsApi)
CODE_CONVERT(_ucReqType)
CODE_CONVERT(_stResult)
CODE_CONVERT(_stTApiKeyValue)
END_CODE_CONVERT(CAnsApi)

/*
*数据更新命令(ID_MAINDB_UPDATEDATA)
*main->db
*/
class CReqUpdateData : public CTCodeObject
{
public:
    int iDataLen;
    int m_iOpType;
    unsigned int    m_uiSwapCount; //更新次数
    CVarObjectKey   m_stKey; //主键
    char* pszData; //数据
};
BEGIN_CODE_CONVERT(CReqUpdateData)
CODE_CONVERT(iDataLen)
CODE_CONVERT(m_iOpType)
CODE_CONVERT(m_uiSwapCount)
CODE_CONVERT(m_stKey)
END_CODE_CONVERT(CReqUpdateData)

class CAnsUpdateData : public CTCodeObject
{
public:
    CResult stResult;
    CVarObjectKey m_stKey;
};
BEGIN_CODE_CONVERT(CAnsUpdateData)
CODE_CONVERT(stResult)
CODE_CONVERT(m_stKey)
END_CODE_CONVERT(CAnsUpdateData)

/*
*数据查询(ID_MAINDB_SELECTDATA)
*main->db
*/
class CReqSelectData : public CTCodeObject
{
public:
    char           m_ucCheckUpdateMgr;
    CVarObjectKey  m_stKey;

};
BEGIN_CODE_CONVERT(CReqSelectData)
CODE_CONVERT(m_ucCheckUpdateMgr)
CODE_CONVERT(m_stKey)
END_CODE_CONVERT(CReqSelectData)

class CAnsSelectData : public CTCodeObject
{
public:
    int     iDataLen;
    CResult stResult;
    char*   pszData; //数据
};
BEGIN_CODE_CONVERT(CAnsSelectData)
CODE_CONVERT(iDataLen)
CODE_CONVERT(stResult)
END_CODE_CONVERT(CAnsSelectData)


#endif //__COMMH_MSG_H__

